package edu.hda.pt.server.connections.netty;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

import edu.hda.pt.server.connections.PTServerNetty;
import edu.hda.pt.utils.Stream;
import edu.hda.pt.utils.TestObject;

/**
 * Event handler for the Netty server
 * 
 * @author Marc Hammerton
 * 
 */
@ChannelPipelineCoverage("all")
public class ServerHandler extends SimpleChannelHandler {

	private PTServerNetty server;

	/**
	 * Constructor setting the server object
	 * 
	 * @param server
	 *            - the server object
	 */
	public ServerHandler(PTServerNetty server) {
		this.server = server;
	}

	/**
	 * This method is called whenever an exception is caught. It prints the
	 * exception.
	 * 
	 * @see org.jboss.netty.channel.SimpleChannelHandler#exceptionCaught(ChannelHandlerContext,
	 *      ExceptionEvent)
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx,
			org.jboss.netty.channel.ExceptionEvent e) throws Exception {
		System.out.println(server.serverID + " Exception: "
				+ ctx.getPipeline().getChannel());
		e.getCause().printStackTrace();
	}

	/**
	 * This method is called when a message from the client is received. It
	 * calls the appropriate server method and sends the response back to the
	 * client.
	 * 
	 * @see org.jboss.netty.channel.SimpleChannelHandler#messageReceived(ChannelHandlerContext,
	 *      MessageEvent)
	 */
	@Override
	public void messageReceived(ChannelHandlerContext chx, MessageEvent e) {

		if (e.getMessage() instanceof Boolean) {
			boolean response = server.handleBool((Boolean) e.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof byte[]) {
			byte[] response = server.handleBytes((byte[]) e.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof Integer) {
			int response = server.handleInteger((Integer) e.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof Long) {
			long response = server.handleLong((Long) e.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof TestObject) {
			TestObject response = server.handleObject((TestObject) e
					.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof String) {
			String response = server.handleString((String) e.getMessage());
			e.getChannel().write(response);
		} else if (e.getMessage() instanceof Stream) {
			Stream stream = (Stream) e.getMessage();
			stream = server.handleStream(stream, e.getChannel());
			if (e.getChannel().isOpen()) {
				e.getChannel().write(stream);
			} else {
				System.out.println("channel closed: " + e.getChannel());
			}
		}

	}
}
